#include <iostream>

#include "aengine.h"

using namespace std;

template<class T> T* AEngine::NewWidget() {
    T* t = new T();
    m_widgets.push_back(t);
    t->SetEngine(this);
    return t;
}

void AEngine::AdditionalInit() {
    //temp fast release hack
    int w = (SDL_GetVideoSurface()->w) / 2;
    int h = (SDL_GetVideoSurface()->h) / 2;
    SDLVideoViewer *sdlvv = NewWidget<SDLVideoViewer > ();
    m_viewers.push_back(sdlvv);
    //sdlvv->Boot("v4l://video2");
    sdlvv->Boot("http://localhost:4481");
    sdlvv->SetPosition(0, 0);
    sdlvv->SetSize(w, h);

    //    sdlvv = NewWidget<SDLVideoViewer > ();
    //    m_viewers.push_back(sdlvv);
    //    sdlvv->Boot("v4l://video7");
    //    sdlvv->SetPosition(w,0); sdlvv->SetSize(w,h);
    //
    //    sdlvv = NewWidget<SDLVideoViewer > ();
    //    m_viewers.push_back(sdlvv);
    //    sdlvv->Boot("v4l://video9");
    //    sdlvv->SetPosition(0,h); sdlvv->SetSize(w,h);
    //
    //    sdlvv = NewWidget<SDLVideoViewer > ();
    //    m_viewers.push_back(sdlvv);
    //    sdlvv->Boot("v4l://video11");
    //    sdlvv->SetPosition(w,h); sdlvv->SetSize(w,h);


    //SDLVideoViewer *sdlvv = new SDLVideoViewer("test");
}

void AEngine::Think(const int& iElapsedTime) {
    // Do time-based calculations
}

void AEngine::Render(SDL_Surface* pDestSurface) {
    vector<SDLWidget*>::iterator it;
    for (it = m_widgets.begin(); it != m_widgets.end(); it++) {
        (*it)->Render();
    }
}

void AEngine::KeyDown(const int& iKeyEnum) {
    switch (iKeyEnum) {
        case SDLK_q:
            Stop();
            break;
        case SDLK_f:
            ToggleFullscreen();
            break;
        case SDLK_r:
            cout << "R " << endl;
            int width, height;
            if (m_viewers[0]->GetMediaEngine()->GetSize(&width, &height)) {
                cout << "AAAAAAA " << width << endl;
                m_viewers[0]->SetSize(width, height);
            }
            break;
        case SDLK_m:
            m_viewers[0]->SetPosition(200, 200);
            break;
        case SDLK_g:
            cout << "G" << endl;
            break;
        case SDLK_LEFT:
            // Left arrow pressed
            break;
        case SDLK_RIGHT:
            // Right arrow pressed
            break;
        case SDLK_UP:
            // Up arrow pressed
            break;
        case SDLK_DOWN:
            // Down arrow pressed
            break;
    }
}

void AEngine::KeyUp(const int& iKeyEnum) {
    switch (iKeyEnum) {
        case SDLK_LEFT:
            // Left arrow released
            break;
        case SDLK_RIGHT:
            // Right arrow released
            break;
        case SDLK_UP:
            // Up arrow released
            break;
        case SDLK_DOWN:
            // Down arrow released
            break;
    }
}

void AEngine::MouseMoved(const int& iButton,
        const int& iX,
        const int& iY,
        const int& iRelX,
        const int& iRelY) {
    // Handle mouse movement

    // iX and iY are absolute screen positions
    // iRelX, iRelY are screen position relative to last detected mouse movement
}

void AEngine::MouseButtonUp(const int& iButton,
        const int& iX,
        const int& iY,
        const int& iRelX,
        const int& iRelY) {
    // Handle mouse button released
}

void AEngine::MouseButtonDown(const int& iButton,
        const int& iX,
        const int& iY,
        const int& iRelX,
        const int& iRelY) {
    // Handle mouse button pressed
}

void AEngine::WindowInactive() {
    // Pause game
}

void AEngine::WindowActive() {
    // Un-pause game
}

void AEngine::End() {
    // Clean up
}
